﻿using System;
using System.Collections.Generic;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.Web.UI.WebControls;
using System.Collections;
using System.Text;
using System.Reflection;
using System.Web.UI;

namespace Havivi.PropertyBagSettings
{
    public class PropertyBagsSettings : PBSPageBase
    {
        protected DropDownList ddlServer;
        protected DropDownList ddlSiteCollection;
        protected DropDownList ddlSite;
        protected DropDownList ddlWebApplications;
        protected DropDownList ddlFolder;
        protected Label lblFarm;
        protected Label PropertyTable;
        protected Label Header;
        protected Label lblSite;
        protected Button btnWebApplication;
        protected Button btnSite;
        protected Button btnFolder;
        protected Button btnSiteCollection;

        const string NS = "No selection";
        const string LIST = "List";
        const string SITE = "Site";
        const string SITE_COLL = "SiteCollection";
        const string WEB_APP = "WebApplication";
        const string FARM = "Farm";
        const string SERVER = "Server";
        const string FARM_HEADER = "<H3 class='ms-standardheader'>Farm: {0} Properties</H3>";
        const string SERVER_HEADER = "<H3 class='ms-standardheader'>Server: {0} Properties</H3>";
        const string LIST_HEADER = "<H3 class='ms-standardheader'>List: {0} Properties <a href=\"{1}/{2}\" target=\"_blank\">{1}/{2}</a></H3>";
        const string SITE_HEADER = "<H3 class='ms-standardheader'>Site: {0} Properties <a href=\"{1}\" target=\"_blank\">{1}</a></H3>";
        const string WEB_APP_HEADER = "<H3 class='ms-standardheader'>Web Application: {0} Properties <a href=\"{1}\" target=\"_blank\">{1}</a></H3>";
        const string NEW_PROP = "<a onclick=\"javascript:window.showModalDialog('ModifyPropertyBag.aspx?mod=new&scope={0}&guid={1}&web={2}&site={3}','','dialogWidth=400px;dialogHeight=400px;center=yes;help=no;scroll=no;status=no;');\" class=\"ms-toolbar\"  onmouseover=\"this.style.cursor='hand';\" >";
        const string MOD_PROP = "<a onmouseover=\"this.style.cursor='hand';\" title='Edit {0} Property'  onclick=\"javascript:window.showModalDialog('ModifyPropertyBag.aspx?mod={1}&scope={2}&guid={3}&web={4}&site={5}&key={0}','','dialogWidth=400px;dialogHeight=400px;center=yes;help=no;scroll=no;status=no;');\">";
        const string EXP_PROP = "<a onclick=\"javascript:window.showModalDialog('ExportPropertyBag.aspx?mod=new&scope={0}&guid={1}&web={2}&site={3}','','dialogWidth=400px;dialogHeight=400px;center=yes;help=no;scroll=no;status=no;');\" class=\"ms-toolbar\"  onmouseover=\"this.style.cursor='hand';\" >";
        const string IMP_PROP = "<a onclick=\"javascript:window.open('ImportPropertyBag.aspx?scope={0}&guid={1}&web={2}&site={3}','_self');\" class=\"ms-toolbar\"  onmouseover=\"this.style.cursor='hand';\" >";

        private string scope = String.Empty;
        private string site = String.Empty;
        private string web = String.Empty;
        private string guid = String.Empty;

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            if (!Page.IsPostBack)
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    if (ddlWebApplications != null)
                    {
                        ddlWebApplications.Items.Clear();
                        ddlSite.Items.Clear();
                        ddlSiteCollection.Items.Clear();
                        ListItem item = new ListItem(NS, NS);
                        ddlWebApplications.Items.Add(item);
                        ddlSiteCollection.Items.Add(item);
                        ddlSite.Items.Add(item);

                        SPFarm farm = SPFarm.Local;
                        SPWebService service = farm.Services.GetValue<SPWebService>("");
                        lblFarm.Text = farm.Name;
                        foreach (SPServer server in farm.Servers)
                        {
                            ListItem ser = new ListItem(server.Name + " (" + server.Address + ")", server.Name);
                            ddlServer.Items.Add(ser);
                        }

                        foreach (SPWebApplication webApp in service.WebApplications)
                        {
                            ListItem webApplication = new ListItem(webApp.Name + " (" + webApp.AlternateUrls.GetResponseUrl(SPUrlZone.Default).Uri.AbsoluteUri.TrimEnd('/') + ")", webApp.AlternateUrls.GetResponseUrl(SPUrlZone.Default).Uri.AbsoluteUri.TrimEnd('/'));
                            ddlWebApplications.Items.Add(webApplication);

                        }
                        scope = "farm";
                        ViewPropertyBag(FARM);
                    }
                    else
                    {
                        lblSite.Text = SPContext.Current.Web.Title;
                        if (!Page.IsPostBack)
                        {
                            scope = "web";
                            ViewPropertyBag(SITE);
                            GetLists();
                        }
                    }

                });
            }

        }

        protected void ddlWebApplications_SelectedIndexChanged(object sender, EventArgs e)
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                ddlSiteCollection.Items.Clear();
                ddlSite.Items.Clear();
                ddlFolder.Items.Clear();
                ListItem item = new ListItem(NS, NS);
                ddlSiteCollection.Items.Add(item);
                ddlSite.Items.Add(item);
                ddlFolder.Items.Add(item);
                if (ddlWebApplications.SelectedValue != NS)
                {
                    SPWebApplication webApp = SPWebApplication.Lookup(new Uri(ddlWebApplications.SelectedValue));
                    SPSiteCollection collSiteCollection = webApp.Sites;
                    foreach (SPSite oSPSite in collSiteCollection)
                    {
                        try
                        {
                            using (SPWeb oSPWeb = oSPSite.OpenWeb())
                            {
                                ListItem siteCollection = new ListItem(oSPWeb.Title + " (" + oSPWeb.Url + ")", oSPWeb.Url);
                                ddlSiteCollection.Items.Add(siteCollection);
                            }
                        }
                        finally
                        {
                            if (oSPSite != null)
                            {
                                oSPSite.Dispose();
                            }
                        }

                    }
                }
                EnabledControls();
            });
        }

        protected void ddlSiteCollection_SelectedIndexChanged(object sender, EventArgs e)
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                ddlSite.Items.Clear();
                ListItem item = new ListItem(NS, NS);
                ddlSite.Items.Add(item);
                if (ddlSiteCollection.SelectedValue != NS)
                {
                    using (SPSite oSPSite = new SPSite(ddlSiteCollection.SelectedValue))
                    {

                        foreach (SPWeb oSPWeb in oSPSite.AllWebs)
                        {
                            if (oSPWeb.Url != oSPSite.Url)
                            {
                                ListItem site = new ListItem(oSPWeb.Title + " (" + oSPWeb.Url + ")", oSPWeb.ServerRelativeUrl);
                                ddlSite.Items.Add(site);
                            }
                            oSPWeb.Dispose();
                        }
                    }

                }
                GetLists(false);
                EnabledControls();
            });
        }

        protected void ddlSite_SelectedIndexChanged(object sender, EventArgs e)
        {
            GetLists(true);
            EnabledControls();
        }

        protected void ddlFolder_SelectedIndexChanged(object sender, EventArgs e)
        {
            EnabledControls();
        }

        private void GetLists(bool SubSite)
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                ddlFolder.Items.Clear();
                ListItem item = new ListItem(NS, NS);
                ddlFolder.Items.Add(item);
                if (ddlSiteCollection.SelectedValue != NS)
                {
                    using (SPSite oSPSite = new SPSite(ddlSiteCollection.SelectedValue))
                    {
                        SPWeb oSPWeb = null;
                        if (SubSite && ddlSite.SelectedValue != NS)
                        {
                            oSPWeb = oSPSite.OpenWeb(ddlSite.SelectedValue);
                        }
                        else
                        {
                            oSPWeb = oSPSite.OpenWeb();
                        }
                        SPListCollection collLists = oSPWeb.Lists;
                        foreach (SPList oList in collLists)
                        {
                            ListItem folder = new ListItem(oList.Title, oList.RootFolder.ToString());
                            ddlFolder.Items.Add(folder);
                        }
                        oSPWeb.Dispose();
                    }
                }
            });
        }

        private void GetLists()
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                ddlFolder.Items.Clear();
                ListItem item = new ListItem(NS, NS);
                ddlFolder.Items.Add(item);

                using (SPSite oSPSite = new SPSite(SPContext.Current.Site.ID))
                {
                    using (SPWeb oSPWeb = oSPSite.AllWebs[SPContext.Current.Web.ID])
                    {

                        SPListCollection collLists = oSPWeb.Lists;
                        foreach (SPList oList in collLists)
                        {
                            ListItem folder = new ListItem(oList.Title, oList.RootFolder.ToString());
                            ddlFolder.Items.Add(folder);
                        }
                    }
                }

            });
        }

        private void ViewPropertyBag(string scope)
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                SPFarm farm;
                PropertyTable.Text = "";
                string siteUrl = "";
                switch (scope)
                {
                    case LIST:

                        if (ddlSiteCollection != null)
                        {
                            siteUrl = ddlSiteCollection.SelectedValue;
                        }
                        else
                        {
                            siteUrl = SPContext.Current.Site.Url;
                        }

                        using (SPSite oSPSite = new SPSite(siteUrl))
                        {
                            site = oSPSite.ID.ToString();
                            SPWeb oSPWeb = null;
                            if (ddlSite == null)
                            {
                                oSPWeb = oSPSite.OpenWeb(SPContext.Current.Web.ServerRelativeUrl);
                            }
                            else if (ddlSite.SelectedValue == NS)
                            {
                                oSPWeb = oSPSite.OpenWeb();
                            }
                            else
                            {
                                oSPWeb = oSPSite.OpenWeb(ddlSite.SelectedValue);
                            }
                            web = oSPWeb.ID.ToString();

                            string[] folders = ddlFolder.SelectedValue.Split('/');

                            SPFolder oSPFolder = null;

                            if (folders.Length > 1)
                            {
                                oSPFolder = oSPWeb.Folders[folders[0]].SubFolders[folders[1]];
                            }
                            else
                            {
                                oSPFolder = oSPWeb.Folders[folders[0]];

                            }
                            guid = oSPFolder.UniqueId.ToString();
                            Header.Text = String.Format(LIST_HEADER, oSPFolder.Name, oSPWeb.Url, oSPFolder.Url);
                            PropertyTable.Text = BuildPropertyTable(oSPFolder.Properties);
                            oSPWeb.Dispose();
                        }
                        break;
                    case SITE:

                        string webUrl = "";
                        if (ddlSiteCollection != null)
                        {
                            siteUrl = ddlSiteCollection.SelectedValue;
                            webUrl = ddlSite.SelectedValue;
                        }
                        else
                        {
                            siteUrl = SPContext.Current.Site.Url;
                            webUrl = SPContext.Current.Web.ServerRelativeUrl;
                        }
                        using (SPSite oSPSite = new SPSite(siteUrl))
                        {
                            site = oSPSite.ID.ToString();
                            using (SPWeb oSPWeb = oSPSite.OpenWeb(webUrl))
                            {
                                web = oSPWeb.ID.ToString();
                                guid = oSPWeb.ID.ToString();
                                Header.Text = String.Format(SITE_HEADER, oSPWeb.Title, oSPWeb.Url);
                                PropertyTable.Text = BuildPropertyTable(oSPWeb.AllProperties);
                            }
                        }
                        break;
                    case SITE_COLL:
                        using (SPSite oSPSite = new SPSite(ddlSiteCollection.SelectedValue))
                        {
                            site = oSPSite.ID.ToString();
                            using (SPWeb oSPWeb = oSPSite.OpenWeb())
                            {
                                web = oSPWeb.ID.ToString();
                                guid = oSPWeb.ID.ToString();
                                Header.Text = String.Format(SITE_HEADER, oSPWeb.Title, oSPWeb.Url);
                                PropertyTable.Text = BuildPropertyTable(oSPWeb.AllProperties);

                            }
                        }
                        break;
                    case FARM:
                        farm = SPFarm.Local;
                        PropertyTable.Text = BuildPropertyTable(farm.Properties);
                        Header.Text = String.Format(FARM_HEADER, farm.Name);
                        break;
                    case SERVER:
                        farm = SPFarm.Local;
                        SPServer server = farm.Servers[ddlServer.SelectedValue];
                        guid = server.Id.ToString();
                        PropertyTable.Text = BuildPropertyTable(server.Properties);
                        Header.Text = String.Format(SERVER_HEADER, server.Name);
                        break;
                    default:
                        SPWebApplication webApp = SPWebApplication.Lookup(new Uri(ddlWebApplications.SelectedValue));
                        guid = webApp.Id.ToString();
                        Header.Text = String.Format(WEB_APP_HEADER, webApp.Name, webApp.AlternateUrls.GetResponseUrl(SPUrlZone.Default).Uri.AbsoluteUri.TrimEnd('/'));
                        PropertyTable.Text = BuildPropertyTable(webApp.Properties);
                        break;

                }
            });
        }

        protected void btnWebApplication_Click(object sender, EventArgs e)
        {
            scope = "app";
            ViewPropertyBag(WEB_APP);
        }

        protected void btnSiteCollection_Click(object sender, EventArgs e)
        {
            scope = "web";
            ViewPropertyBag(SITE_COLL);
        }

        protected void btnSite_Click(object sender, EventArgs e)
        {
            scope = "web";
            ViewPropertyBag(SITE);
        }

        protected void btnFolder_Click(object sender, EventArgs e)
        {
            scope = "lst";
            if (ddlFolder.SelectedValue != NS)
            {
                ViewPropertyBag(LIST);
            }
            else
            {
                PropertyTable.Text = "";
                Header.Text = "";
            }
        }

        private void EnabledControls()
        {
            PropertyTable.Text = "";
            Header.Text = "";

            if (ddlWebApplications.SelectedValue != NS)
            {
                btnWebApplication.Enabled = true;
            }
            else
            {
                btnWebApplication.Enabled = false;
            }

            if (ddlWebApplications.Items.Count > 1)
            {
                ddlWebApplications.Enabled = true;
            }
            else
            {
                ddlWebApplications.Enabled = false;
            }

            if (ddlSiteCollection.SelectedValue != NS)
            {
                btnSiteCollection.Enabled = true;
            }
            else
            {
                btnSiteCollection.Enabled = false;
            }

            if (ddlSiteCollection.Items.Count > 1)
            {
                ddlSiteCollection.Enabled = true;
            }
            else
            {
                ddlSiteCollection.Enabled = false;
            }

            if (ddlSite.SelectedValue != NS)
            {
                btnSite.Enabled = true;
            }
            else
            {
                btnSite.Enabled = false;
            }

            if (ddlSite.Items.Count > 1)
            {
                ddlSite.Enabled = true;
            }
            else
            {
                ddlSite.Enabled = false;
            }

            if (ddlFolder.SelectedValue != NS)
            {
                btnFolder.Enabled = true;
            }
            else
            {
                btnFolder.Enabled = false;
            }

            if (ddlFolder.Items.Count > 1)
            {
                ddlFolder.Enabled = true;
            }
            else
            {
                ddlFolder.Enabled = false;
            }
        }

        private string BuildPropertyTable(Hashtable properties)
        {
            string classStyle = "";
            StringBuilder sb = new StringBuilder();
            sb.Append("<br />");
            sb.Append("<table class=\"ms-toolbar\" width=\"100%\" style=\"padding-left: 3px; padding-right: 5px;\" cellspacing=\"0\" cellpadding=\"2\">");
            sb.Append("<tr>");
            sb.Append("<td>");
            sb.Append("<table cellspacing=\"1\" cellpadding=\"0\" border=\"0\">");
            sb.Append("<tr>");
            sb.Append("<td width=\"0\" class=\"ms-toolbar\">");
            sb.Append(String.Format(NEW_PROP, scope, guid, web, site));
            sb.Append("<img alt=\"New Property\" src=\"/_layouts/images/newitem.gif\" border=\"0\" hspace=\"2\" /></a>");
            sb.Append("</td>");
            sb.Append("<td class=\"\" nowrap>");
            sb.Append(String.Format(NEW_PROP, scope, guid, web, site));
            sb.Append("New Property</a>");
            sb.Append("</td>");
            sb.Append("<td class=\"ms-toolbar\" style=\"width: 10px;\">&nbsp;</td>");
            sb.Append("<td class=\"ms-toolbar\">");
            sb.Append(String.Format(EXP_PROP, scope, guid, web, site));
            sb.Append("<img alt=\"Export Properties<\" src=\"/_layouts/images/EXPTITEM.GIF\" border=\"0\" hspace=\"2\" /></a>");
            sb.Append("</td>");
            sb.Append("<td class=\"\"  nowrap>");
            sb.Append(String.Format(EXP_PROP, scope, guid, web, site));
            sb.Append("Export Properties</a>");
            sb.Append("</td>");
            sb.Append("<td class=\"ms-toolbar\" style=\"width: 10px;\">&nbsp;</td>");
            sb.Append("<td class=\"ms-toolbar\">");
            sb.Append(String.Format(IMP_PROP, scope, guid, web, site));
            sb.Append("<img alt=\"Import Properties<\" src=\"/_layouts/images/IMPITEM.GIF\" border=\"0\" hspace=\"2\" /></a>");
            sb.Append("</td>");
            sb.Append("<td class=\"\"  nowrap>");
            sb.Append(String.Format(IMP_PROP, scope, guid, web, site));
            sb.Append("Import Properties</a>");
            sb.Append("</td>");
            sb.Append("</tr>");
            sb.Append("</table>");
            sb.Append("</td>");
            sb.Append("</tr>");
            sb.Append("</table>");
            sb.Append("<br />");
            sb.Append("<table class=\"ms-listviewtable\" width=\"100%\" style=\"padding-left: 3px; padding-right: 5px;\" cellspacing=\"0\" cellpadding=\"2\">");
            sb.Append("<tr class='ms-viewheadertr'>");
            sb.Append("<td class='ms-vh2-nofilter ms-vh2-gridview'>Property</td>");
            sb.Append("<td class='ms-vh2-nofilter ms-vh2-gridview'>Value</td>");
            sb.Append("<td class='ms-vh2-nofilter ms-vh2-gridview' style=\"text-align:center\">Edit</td>");
            sb.Append("<td class='ms-vh2-nofilter ms-vh2-gridview' style=\"text-align:center\">Delete</td>");
            sb.Append("</tr>");



            List<SortedProperties> sp = new List<SortedProperties>();

            foreach (DictionaryEntry property in properties)
            {
                if (property.Value != null)
                {
                    sp.Add(new SortedProperties(property.Key.ToString(), property.Value.ToString()));
                }
            }

            sp.Sort(new GenericComparer<SortedProperties>("Key", GenericComparer<SortedProperties>.SortOrder.Ascending));

            foreach (SortedProperties property in sp)
            {
                sb.Append("<tr" + classStyle + ">");
                sb.Append("<td class='ms-vb2'>" + property.Key + "</td>");
                sb.Append("<td class='ms-vb2'>" + property.Value + "</td>");
                sb.Append("<td class='ms-vb2' style=\"text-align:center\">");
                sb.Append(String.Format(MOD_PROP, property.Key.ToString(), "edt", scope, guid, web, site));
                sb.Append("<img src='../_layouts/images/EDITITEM.GIF' border='0' alt='Edit " + property.Key + " Property' ></a></td>");
                sb.Append("<td   class='ms-vb2' style=\"text-align:center\">");
                sb.Append(String.Format(MOD_PROP, property.Key.ToString(), "del", scope, guid, web, site));
                sb.Append("<img src='../_layouts/images/DELITEM.GIF' border='0' alt='Delete " + property.Key + " Property'></a></td>");
                sb.Append("</tr>");

                if (classStyle == "")
                {
                    classStyle = " class='ms-alternating'";
                }
                else
                {
                    classStyle = "";
                }
            }
            sb.Append("</table>");

            return sb.ToString();
        }

        public ICollection SortedHashTable(Hashtable ht)
        {
            ArrayList sorter = new ArrayList();
            sorter.AddRange(ht);
            sorter.Sort();
            return sorter;
        }

        protected void btnFarm_Click(object sender, EventArgs e)
        {
            scope = "farm";
            ViewPropertyBag(FARM);
        }

        protected void btnServer_Click(object sender, EventArgs e)
        {
            scope = "ser";
            ViewPropertyBag(SERVER);
        }

        protected override void RenderChildren(HtmlTextWriter output)
        {
            LiteralControl pbsBreadcrumb = null;
            if (SPContext.Current.Site.WebApplication.IsAdministrationWebApplication)
            {
                pbsBreadcrumb = new LiteralControl("<a href='" + SPContext.Current.Web.Url + "'>" + SPContext.Current.Web.Title + "</a>" + " > <a href='" + SPContext.Current.Web.Url + "/_admin/Operations.aspx'> Operations </a> > Property Bag Settings ");
            }
            else
            {
                pbsBreadcrumb = new LiteralControl("<a href='" + SPContext.Current.Web.Url + "'>" + SPContext.Current.Web.Title + "</a>" + " > <a href='" + SPContext.Current.Web.Url + "/_layouts/settings.aspx'> Site Settings </a> > Property Bag Settings ");
            }
            Master.FindControl("PlaceHolderTitleBreadcrumb").FindControl("ContentMap").Controls.Add(pbsBreadcrumb);

            base.RenderChildren(output);

        }

    }
}